home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / PASCAL / 0920.ZIP / STRING.ARC / STRINGS.ASM < prev    next >
Assembly Source File  |  1987-12-26  |  23KB  |  508 lines

  1.            PAGE    55,132
  2. CODE       SEGMENT BYTE PUBLIC
  3.            ASSUME  CS:CODE
  4.            PUBLIC  UPPERCASE
  5.            PUBLIC  STRINGOF
  6.            PUBLIC  TRANSLATE
  7.            PUBLIC  EXTRACTTOCHAR
  8.            PUBLIC  EXTRACTFORCOUNT
  9.            PUBLIC  PADLEFT
  10.            PUBLIC  PADRIGHT
  11.  
  12.             PAGE
  13. ;----------------------------------------------------------------------
  14. ; PROTOTYPE:   STRING := UPPERCASE(STRING1);
  15. ;
  16. ;    STRING     === ANY VALID TP4 STRING VARIABLE
  17. ;    STRING1    === ANY VALID TP4 STRING VARIABLE
  18. ;----------------------------------------------------------------------
  19. ; THE EFFECT OF THIS ROUTINE IS AS IF YOU HAD CODED THE FOLLOWING;
  20. ;
  21. ;    FOR I := 1 TO LENGTH(STRING1) DO
  22. ;      STRING[I] := UPCASE(STRING1[I]);
  23. ;
  24. ;---------------------------------------------------------------------
  25. UCRESULT   EQU     DWORD PTR [BP+10]    ;POS OF RESULT PTR IN STACK
  26. UCSTRING   EQU     DWORD PTR [BP+6]     ;POS OF STRING PTR IN STACK
  27.  
  28. UPPERCASE  PROC    FAR
  29.            PUSH    BP                   ;SAVEBP
  30.            MOV     BP,SP                ;SETUP STACK FRAME
  31.            PUSH    DS                   ;SAVE DATA SEGMENT POINTER
  32.            LDS     SI,UCSTRING          ;LOAD SOURCE ADDRESSES
  33.            LES     DI,UCRESULT          ;LOAD RESULT ADDRESSES
  34.            CLD                          ;SET DIRECTION TO FORWARD
  35.            LODSB                        ;MOVE THE STRING LENGTH
  36.            STOSB                        ;
  37. ;
  38. ; SETUP THE LENGTH IN CX AND MAKE SURE THERE IS SOMETHING TO DO
  39. ;
  40.            MOV     CL,AL                ;COPY STRING LENGTH TO CX
  41.            XOR     CH,CH                ;CLEAR HIGH ORDER WORD
  42.            JCXZ    UCEXIT               ;EXIT IF LENGTH = ZERO
  43. ;
  44. ; NOW WE LOOP CHECKING EACH BYTE AND WHERE NEEDED CONVERTING THE CASE
  45. ;
  46. UCLOOP:
  47.             LODSB                       ;LOAD NEXT STRING CHARACTER
  48.             CMP    AL,'a'               ;Q. LESS THAN 'A'
  49.             JB     UCSTORE              ;A. YES--THEN WE DONT WANT IT
  50.             CMP    AL,'z'               ;Q. GREATER THAN 'Z'
  51.             JA     UCSTORE              ;A. YES--THEN WE DONT WANT IT
  52.             SUB    AL,'a'-'A'           ;A. NO--CHANGE IT TO UPPER CASE
  53. UCSTORE:
  54.             STOSB                       ;STORE BYTE INTO RESULT STRING
  55.             LOOP   UCLOOP               ;GO PROCESS NEXT BYTE
  56. ;
  57. ; ALL DONE SO RESTORE THE STUFF WE SAVED AND RETURN TO CALLER
  58. ;
  59. UCEXIT:
  60.             POP    DS                   ;RESTORE DATA SEGMENT PTR
  61.             POP    BP                   ;RESTORE BASE POINTER
  62.             RET    4                    ;REMOVE PARAM AND RETURN
  63. UPPERCASE   ENDP
  64.  
  65.             PAGE
  66. ;----------------------------------------------------------------------
  67. ; PROTOTYPE:   STRING := STRINGOF(CHARACTER, LENGTH);
  68. ;
  69. ;    STRING     === ANY VALID TP4 STRING VARIABLE
  70. ;    CHARACTER  === ANY VALID CHARACTER
  71. ;    LENGTH     === THE NUMBER OF BYTES TO FILL WITH CHARACTER
  72. ;----------------------------------------------------------------------
  73. ; THE EFFECT OF THIS ROUTINE IS AS IF YOU HAD CODED THE FOLLOWING;
  74. ;
  75. ;    FOR I := 1 TO LENGTH DO
  76. ;      STRING[I] := CHARACTER;
  77. ;
  78. ; IT IS THE USERS RESPONSIBILITY TO INSURE THAT THE STRING IS LARGE
  79. ; ENOUGH TO CONTAIN 'LENGTH' REPITIONS OF CHARACTER.
  80. ;---------------------------------------------------------------------
  81. SORESULT    EQU    DWORD PTR [BP+10]    ;STACK POS OF RESULT PTR
  82. SOCHAR      EQU    BYTE  PTR [BP+8]     ;STACK POS OF FILL CHARACTER
  83. SOCOUNT     EQU    BYTE  PTR [BP+6]     ;STACK POS OF FILL LENGTH
  84.  
  85. STRINGOF    PROC   FAR
  86.             PUSH   BP                   ;SAVE BASE POINTER
  87.             MOV    BP,SP                ;SETUP STACK FRAME
  88. ;
  89. ; NOW PICK UP THE PARAMETERS AND MAKE SURE WE FILL AT LEAST 1 BYTE
  90. ;
  91.             LES    DI,SORESULT          ;LOAD ADDRESS OF RESULT
  92.             MOV    AL,SOCOUNT           ;LOAD LENGTH OF FILL
  93.             OR     AL,AL                ;Q. IS LENGTH ZERO
  94.             JZ     SOEXIT               ;A. YES--THEN NOTHING TO DO
  95.             CLD                         ;SET DIRECTION TO FORWARD
  96.             STOSB                       ;SET LENGTH OF RESULT
  97.             MOV    CL,AL                ;COPY LENGTH TO CX
  98.             XOR    CH,CH                ;CLEAR HIGH ORDER BYTE
  99.             MOV    AL,SOCHAR            ;LOAD THE FILL CHARACTER
  100.             REP    STOSB                ;FILL STRING WITH CHARACTER
  101. ;
  102. ; ALL DONE SO RESTORE THE STUFF WE SAVED AND RETURN TO THE CALLER
  103. ;
  104. SOEXIT:
  105.             POP    BP                   ;RESTORE BASE POINTER
  106.             RET    4                    ;REMOVE AND RETURN
  107. STRINGOF    ENDP
  108.  
  109.             PAGE
  110. ;----------------------------------------------------------------------
  111. ; PROTOTYPE:   TRANSLATE(STRING_NAME,TRANSLATE_TABLE);
  112. ;
  113. ;    STRING_NAME === THE NAME OF ANY VALID TP4 STRING VARIABLE
  114. ;
  115. ;    TRANSLATE_TABLE === THE NAME OF A 256 BYTE TRANSLATION TABLE.
  116. ;----------------------------------------------------------------------
  117. ; THE EFFECT OF THIS ROUTINE IS AS IF YOU HAD CODED THE FOLLOWING;
  118. ;
  119. ;    STRING[I] := TRANSLATE_TABLE[ORD(STRING[I])];
  120. ;
  121. ; IT IS THE USERS RESPONSIBILITY TO INSURE THAT THE TRANSLATE TABLE
  122. ; IS AT LEAST 256 BYTES IN LENGTH.
  123. ;---------------------------------------------------------------------
  124. TSSTRING    EQU    DWORD PTR [BP+10]    ;STACK POS OF RESULT PTR
  125. TSTABLE     EQU    DWORD PTR [BP+6]     ;STACK POS OF FILL LENGTH
  126.  
  127. TRANSLATE   PROC   FAR
  128.             PUSH   BP                   ;SAVE BASE POINTER
  129.             MOV    BP,SP                ;SETUP STACK FRAME
  130.             PUSH   DS                   ;SAVE DATA SEGMENT POINTER
  131. ;
  132. ; NOW PICK UP THE PARAMETERS AND MAKE SURE WE FILL AT LEAST 1 BYTE
  133. ;
  134.             LES    DI,TSSTRING          ;LOAD ADDR OF STRING
  135.             LDS    BX,TSTABLE           ;LOAD ADDR OF TRANSLATE TABLE
  136.             MOV    SI,DI                ;SET SOURCE = DESTINATION
  137. ;
  138. ; NOW GET THE STRING LENGTH AND MAKE SURE IT IS NOT ZERO
  139. ;
  140.             LODSB                       ;LOAD THE STRING LENGTH
  141.             MOV    CL,AL                ;COPY INTO CX AND
  142.             SUB    CH,CH                ;CLEAR HIGH ORDER BYTE
  143.             JCXZ   TSEXIT               ;Q. IS LENGTH ZERO
  144.             INC    DI                   ;A. NO--MAKE DI MATCH SI
  145.             CLD                         ;SET DIRECTION TO FORWARD
  146. ;
  147. ; HERE IS THE MAIN TRANSLATION LOOP
  148. ;
  149. TSLOOP:
  150.             LODSB                       ;LOAD A SOURCE BYTE
  151.             XLAT                        ;TRANSLATE THE BYTE
  152.             STOSB                       ;STORE BACK INTO STRING
  153.             LOOP   TSLOOP               ;GO PROCESS NEXT BYTE
  154. ;
  155. ; ALL DONE SO RESTORE THE STUFF WE SAVED AND RETURN TO THE CALLER
  156. ;
  157. TSEXIT:
  158.             POP    DS                   ;RESTORE DATA SEGMENT
  159.             POP    BP                   ;RESTORE BASE POINTER
  160.             RET    8                    ;REMOVE AND RETURN
  161. TRANSLATE   ENDP
  162.  
  163.             PAGE
  164. ;----------------------------------------------------------------------
  165. ; TARGET := EXTRACTTOCHAR(SOURCE,SIZEOF(TARGET),BOUNDARY_CHAR);
  166. ;
  167. ;    TARGET        === THE NAME OF ANY VALID TP4 STRING VARIABLE
  168. ;    SOURCE        === THE NAME OF ANY VALID TP4 STRING VARIABLE
  169. ;    SIZEOF(X)     === THE VALUE RETURN BY SIZEOF FOR TAGET
  170. ;    BOUNDARY_CHAR === ANY VALID CHARACTER
  171. ;----------------------------------------------------------------------
  172. ; IT IS THE USERS RESPONSIBILITY TO INSURE THAT THE TARGET STRING IS
  173. ; LARGE ENOUGH TO CONTAIN THE EXTRACTED STRING.
  174. ;---------------------------------------------------------------------
  175. EXTARGET    EQU    DWORD PTR [BP+14]    ;STACK POS OF RESULT PTR
  176. EXSOURCE    EQU    DWORD PTR [BP+10]    ;STACK POS OF RESULT PTR
  177. EXTRGLEN    EQU    WORD  PTR [BP+8]     ;STACK POS OF RESULT LENGTH
  178. EXCHAR      EQU    BYTE  PTR [BP+6]     ;STACK POS OF BOUNDARY CHAR
  179.  
  180. EXTRACTTOCHAR     PROC   FAR
  181.             PUSH   BP                   ;SAVE BASE POINTER
  182.             MOV    BP,SP                ;SETUP STACK FRAME
  183.             PUSH   DS                   ;SAVE DATA SEGMENT POINTER
  184. ;
  185. ; NOW PICK UP THE PARAMETERS AND MAKE SURE WE FILL AT LEAST 1 BYTE
  186. ;
  187.             LES    DI,EXTARGET          ;LOAD ADDR OF TARGET STRING
  188.             LDS    SI,EXSOURCE          ;LOAD ADDR OF SOURCE STRING
  189.             MOV    AH,EXCHAR            ;LOAD THE BOUNDARY CHARACTER
  190. ;
  191. ; SET THE SOURCE LENGTH TO ZERO IN CASE THERE IS NOTHING TO DO
  192. ;
  193.             SUB    AL,AL                ;CLEAR AL
  194.             STOSB                       ;SET TARGET LENGTH TO ZERO
  195. ;
  196. ; NOW GET THE STRING LENGTH AND MAKE SURE IT IS NOT ZERO
  197. ;
  198.             LODSB                       ;LOAD THE STRING LENGTH
  199.             MOV    CL,AL                ;COPY INTO CX AND
  200.             SUB    CH,CH                ;CLEAR HIGH ORDER BYTE
  201.             JCXZ   EXEXIT               ;Q. IS LENGTH ZERO
  202.             SUB    BL,BL                ;A. NO--CLEAR EXTRACTED LENGTH
  203.             MOV    DX,EXTRGLEN          ;LOAD MAXIMUM LENGTH OF TARGET
  204.             CLD                         ;SET DIRECTION TO FORWARD
  205. ;
  206. ; HERE IS THE MAIN TRANSLATION LOOP
  207. ;
  208. EXLOOP:
  209.             LODSB                       ;LOAD A SOURCE BYTE
  210.             CMP    AH,AL                ;Q. IS IT THE BOUNDARY CHAR
  211.             JE     EXBOUND              ;A. YES--GO CLEAN UP THINGS
  212.             STOSB                       ;A. NO--STORE CHAR INTO TARGET
  213.             INC    BL                   ;INCREMENT EXTRACTED CHAR COUNT
  214.             DEC    DX                   ;Q. ANY ROOM LEFT IN TARGET
  215.             JZ     EXBOUND              ;A. NO--THEN STOP MOVING
  216.             LOOP   EXLOOP               ;GO PROCESS NEXT BYTE
  217. ;
  218. ; WE HAVE FOUND THE BOUNDARY CHARACTER SO SET THE TARGET LENGTH
  219. ; AND DELETE THE EXTRACTED CHARACTERS FROM THE SOURCE STRING
  220. ;
  221. EXBOUND:
  222.             LES    DI,EXTARGET          ;RELOAD ADDR OF TARGET
  223.             MOV    AL,BL                ;COPY EXTRACTED LENGTH TO AL
  224.             STOSB                       ;SET TARGET STRING LENGTH
  225. ;
  226. ; NOW WE MUST REMOVE THE EXTRACTED CHARACTERS FROM THE SOURCE STRING
  227. ;
  228.             LES    DI,EXSOURCE          ;RELOAD ADDR OF SOURCE
  229.             LDS    SI,EXSOURCE          ;AND ONCE MORE FOR MOVE
  230.             LODSB                       ;AL = SOURCE STRING LENGTH
  231.             SUB    BH,BH                ;CLEAR HIGH ORDER BX
  232.             ADD    SI,BX                ;OFFSET TO BOUNDARY FOUND
  233.             SUB    AL,BL                ;LENGTH = LENGTH - EXTRACT_CNT
  234.             STOSB                       ;STORE NEW SOURCE LENGTH
  235.             MOV    CL,AL                ;SETUP TO MOVE REST OF SOURCE
  236.             SUB    CH,CH                ;
  237.             REP    MOVSB                ;LEFT ALIGN REMAINING SOURCE
  238. ;
  239. ; ALL DONE SO RESTORE THE STUFF WE SAVED AND RETURN TO THE CALLER
  240. ;
  241. EXEXIT:
  242.             POP    DS                   ;RESTORE DATA SEGMENT
  243.             POP    BP                   ;RESTORE BASE POINTER
  244.             RET    8                    ;REMOVE AND RETURN
  245. EXTRACTTOCHAR     ENDP
  246.  
  247.             PAGE
  248. ;----------------------------------------------------------------------
  249. ; TARGET := EXTRACTFORCOUNT(SOURCE,SIZEOF(TARGET),COUNT);
  250. ;
  251. ;    TARGET        === THE NAME OF ANY VALID TP4 STRING VARIABLE
  252. ;    SOURCE        === THE NAME OF ANY VALID TP4 STRING VARIABLE
  253. ;    SIZEOF(X)     === THE VALUE RETURN BY SIZEOF FOR TAGET
  254. ;    COUNT         === NUMBER OF CHARACTERS TO EXTRACT
  255. ;----------------------------------------------------------------------
  256. ; THE EFFECT OF THIS ROUTINE IS AS IF YOU HAD CODED THE FOLLOWING;
  257. ;
  258. ;    STRING := COPY(STRING,1,COUNT);
  259. ;    DELETE(STRINGT,1,COUNT);
  260. ;
  261. ; IT IS THE USERS RESPONSIBILITY TO INSURE THAT THE TARGET STRING IS
  262. ; LARGE ENOUGH TO CONTAIN THE EXTRACTED STRING.
  263. ;---------------------------------------------------------------------
  264. ECTARGET    EQU    DWORD PTR [BP+14]    ;STACK POS OF RESULT PTR
  265. ECSOURCE    EQU    DWORD PTR [BP+10]    ;STACK POS OF SOURCE PTR
  266. ECTRGLEN    EQU    WORD  PTR [BP+8]     ;STACK POS OF RESULT LENGTH
  267. ECCOUNT     EQU    BYTE  PTR [BP+6]     ;STACK POS OF COUNT
  268.  
  269. EXTRACTFORCOUNT    PROC   FAR
  270.             PUSH   BP                   ;SAVE BASE POINTER
  271.             MOV    BP,SP                ;SETUP STACK FRAME
  272.             PUSH   DS                   ;SAVE DATA SEGMENT POINTER
  273. ;
  274. ; LOAD ADDR OF TARGET AND SET LENGTH TO ZERO
  275. ;
  276.             LES    DI,ECTARGET          ;LOAD ADDR OF TARGET STRING
  277.             SUB    AL,AL                ;CLEAR AL
  278.             STOSB                       ;SET TARGET LENGTH TO ZERO
  279.             DEC    DI                   ;BACKUP TO LENGTH BYTE
  280. ;
  281. ; LOAD ADDR OF SOURCE AND VALIDATE LENGTH AND COUNT
  282. ;
  283. ECCHKSRC:
  284.             LDS    SI,ECSOURCE          ;LOAD ADDR OF SOURCE STRING
  285.             LODSB                       ;GET THE SOURCE LENGTH
  286.             CMP    AL,0                 ;Q. IS SOURCE LENGTH ZERO
  287.             JE     ECEXIT               ;A. YES--THEN DO NOTHING
  288. ;
  289. ; SOURCE_LEN IS NOT ZERO...BUT IS IT => COUNT ?
  290. ;
  291.             MOV    AH,ECCOUNT           ;LOAD THE EXTRACT COUNT
  292.             CMP    AL,AH                ;Q. SOURCE_LEN => COUNT
  293.             JAE    ECSETLEN             ;A. YES--ALL IS OKAY
  294.             MOV    AH,AL                ;A. NO--COUNT = SOURCE_LEN
  295. ;
  296. ; SOURCE_LEN WAS < COUNT...SET COUNT = SOURCE_LEN
  297. ;
  298. ECSETLEN:
  299.             MOV    CL,AH                ;MOVE FINAL LENGTH TO CX
  300.             SUB    CH,CH                ;
  301.             MOV    BX,CX                ;SAVE LENGTH OF MOVE
  302. ;
  303. ; SEE IF TARGET IS LARGE ENOUGH TO HOLD THE EXTRACTED STRING
  304. ;
  305.             MOV    DX,EXTRGLEN          ;LOAD MAX SIZE OF TARGET
  306.             DEC    DX                   ;ADJUST FOR LENGTH BYTE
  307.             CMP    DX,CX                ;Q. IS TARGET LARGE ENOUGH
  308.             JAE    ECMOVE               ;A. YES--GO DO THE MOVE
  309.             MOV    BX,DX                ;A. NO--TARGET_LEN = MOVE LEN
  310.             MOV    CX,DX                ;MOVE_LEN = TARGET_LEN
  311. ;
  312. ; TARGET WAS LARGE ENOUGH...SET TARGET_LEN TO EXTRACTED_STRING_LEN
  313. ;
  314. ECMOVE:
  315.             MOV    AL,CL                ;MOVE FINAL LENGTH TO AL
  316.             STOSB                       ;SET TARGET LENGTH TO ZERO
  317. ;
  318. ; NOW WE CAN MOVE THE BYTES FROM SOURCE TO TARGET
  319. ;
  320.             CLD                         ;SET DIRECTION TO FORWARD
  321.             REP    MOVSB                ;COPY FROM SOURCE TO TARGET
  322. ;
  323. ; NOW WE MUST REMOVE THE EXTRACTED CHARACTERS FROM THE SOURCE STRING
  324. ;
  325.             LES    DI,ECSOURCE          ;RELOAD ADDR OF SOURCE
  326.             LDS    SI,ECSOURCE          ;AND ONCE MORE FOR MOVE
  327.             LODSB                       ;AL = SOURCE STRING LENGTH
  328.             SUB    AH,AH                ;CLEAR HIGH ORDER BYTE
  329.             MOV    CX,BX                ;RESTORE EXTRACTED LENGTH
  330. ;
  331. ; NOW COMPUTE THE NEW SOURCE LENGTH AND ADJUST THE SOURCE STRING
  332. ;
  333.             ADD    SI,CX                ;OFFSET TO 1ST BYTE NOT MOVED
  334.             SUB    AX,CX                ;NEW_LEN = SRC_LEN - XTRCT_LEN
  335.             STOSB                       ;SET SRC_LEN = NEW_LEN
  336.             JZ     ECEXIT               ;EXIT IF CURR_LEN = 0
  337.             MOV    CX,AX                ;MOVE LENGTH = NEW_LENGTH
  338.             CLD                         ;SET DIRECTION TO FORWARD
  339.             REP    MOVSB                ;LEFT ALIGN REMAINING SOURCE
  340. ;
  341. ; ALL DONE SO RESTORE THE STUFF WE SAVED AND RETURN TO THE CALLER
  342. ;
  343. ECEXIT:
  344.             POP    DS                   ;RESTORE DATA SEGMENT
  345.             POP    BP                   ;RESTORE BASE POINTER
  346.             RET    8                    ;REMOVE AND RETURN
  347. EXTRACTFORCOUNT    ENDP
  348.  
  349.             PAGE
  350. ;----------------------------------------------------------------------
  351. ; PADLEFT(STRING,SIZEOF(TARGET),TARGET_LEN,PAD_CHAR);
  352. ;
  353. ;    STRING        === THE NAME OF ANY VALID TP4 STRING VARIABLE
  354. ;    SIZEOF(X)     === THE VALUE RETURN BY SIZEOF FOR TAGET
  355. ;    TARGET_LEN    === DESIRED LENGTH AFTER PADDING
  356. ;    PAD_CHAR      === ANY VALID CHARACTER
  357. ;----------------------------------------------------------------------
  358. ; THE EFFECT OF THIS ROUTINE IS AS IF YOU HAD CODED THE FOLLOWING;
  359. ;
  360. ;    STRING[I] := TRANSLATE_TABLE[ORD(STRING[I])];
  361. ;
  362. ; IT IS THE USERS RESPONSIBILITY TO INSURE THAT THE TARGET STRING IS
  363. ; LARGE ENOUGH TO CONTAIN THE EXTRACTED STRING.
  364. ;---------------------------------------------------------------------
  365. PLSTRING    EQU    DWORD PTR [BP+12]    ;STACK POS OF STRING PTR
  366. PLMAXLEN    EQU    WORD  PTR [BP+10]    ;STACK POS OF MAX LENGTH
  367. PLTRGLEN    EQU    WORD  PTR [BP+8]     ;STACK POS OF DESIRED LENGTH
  368. PLCHAR      EQU    BYTE  PTR [BP+6]     ;STACK POS OF PAD CHAR
  369.  
  370. PADLEFT     PROC   FAR
  371.             PUSH   BP                   ;SAVE BASE POINTER
  372.             MOV    BP,SP                ;SETUP STACK FRAME
  373.             PUSH   DS                   ;SAVE DATA SEGMENT POINTER
  374. ;
  375. ; PICK UP THE VARIOUS PARAMETERS
  376. ;
  377.             CLD                         ;DIRECTION = FORWARD
  378.             LDS    SI,PLSTRING          ;LOAD ADDR OF SOURCE STRING
  379.             LES    DI,PLSTRING          ;LOAD STRING PTR AS DESTINATION
  380.             MOV    BX,PLMAXLEN          ;LOAD THE MAXIMUM STRING LEN
  381.             MOV    CX,PLTRGLEN          ;LOAD THE DESIRED LENGTH
  382.             MOV    AH,PLCHAR            ;LOAD THE PAD CHARACTER
  383. ;
  384. ; SEE IF WHAT THE CALLER WANTS WILL FIT
  385. ;
  386.             DEC    BX                   ;DECREMENT FOR LENGTH BYTE
  387.             LODSB                       ;LOAD THE CURRENT STRING LENGTH
  388.             SUB    AH,AH                ;CLEAR HIGH ORDER BYTE
  389.             CMP    AX,BX                ;Q. CUR_LEN => MAX_LEN
  390.             JAE    PLEXIT               ;A. YES--THEN JUST QUIT
  391.             CMP    AX,CX                ;Q. CURR_LEN > DESIRED_LEN
  392.             JAE    PLEXIT               ;A. YES--THEN NOTHING TO DO
  393.             CMP    CX,BX                ;Q. DESIRED_LEN > MAX_LEN
  394.             JBE    PLSIZEOK             ;A. NO--LENGTHS ARE OKAY
  395.             MOV    CX,BX                ;A. YES--DESIRED_LEN = MAX_LEN
  396. PLSIZEOK:
  397.             SUB    CX,AX                ;PAD_LEN = DESIRED_LEN - CUR_LEN
  398.             MOV    BX,CX                ;SAVE PAD_LEN IN BX
  399. ;
  400. ; ALL IS OKAY, SO MOVE THE STRING RIGHT TO MAKE ROOMM FOR LEFT PAD
  401. ;
  402.             MOV    SI,DI                ;SI = DI = 1ST BYTE OF STRING
  403.             ADD    DI,PLTRGLEN          ;DI ==> COMPUTED STRING END
  404.             ADD    SI,AX                ;SI ==> LAST STRING DATA BYTE
  405.             MOV    CX,AX                ;MOVE OLD_LEN BYTES
  406.             STD                         ;DIRECTION = BACKWARDS
  407.             REP    MOVSB                ;MOVE STRING RIGHT 'N' BYTES
  408. ;
  409. ; FILL THE VACANT SPACE ON THE LEFT WILL 'PLCHAR'
  410. ;
  411.             CLD                         ;DIRECTION = FORWARD
  412.             LES    DI,PLSTRING          ;LOAD ADDR OF STRING AGAIN
  413.             MOV    AX,PLTRGLEN          ;LOAD LENGTH OF PAD
  414.             STOSB                       ;SET NEW LENGTH OF STRING
  415.             MOV    AL,PLCHAR            ;LOAD THE PAD CHARACTER
  416.             MOV    CX,BX                ;RESTORE PAD_LEN
  417.             CLD                         ;SET DIRECTION TO FORWARD
  418.             REP    STOSB                ;PAD THE STRING
  419. ;
  420. ; ALL DONE SO RESTORE THE STUFF WE SAVED AND RETURN TO THE CALLER
  421. ;
  422. PLEXIT:
  423.             POP    DS                   ;RESTORE DATA SEGMENT
  424.             POP    BP                   ;RESTORE BASE POINTER
  425.             RET    8                    ;REMOVE AND RETURN
  426. PADLEFT     ENDP
  427.  
  428.             PAGE
  429. ;----------------------------------------------------------------------
  430. ; PADRIGHT(STRING,SIZEOF(TARGET),TARGET_LEN,PAD_CHAR);
  431. ;
  432. ;    STRING        === THE NAME OF ANY VALID TP4 STRING VARIABLE
  433. ;    SIZEOF(X)     === THE VALUE RETURN BY SIZEOF FOR TAGET
  434. ;    TARGET_LEN    === DESIRED LENGTH AFTER PADDING
  435. ;    PAD_CHAR      === ANY VALID CHARACTER
  436. ;----------------------------------------------------------------------
  437. ; THE EFFECT OF THIS ROUTINE IS AS IF YOU HAD CODED THE FOLLOWING;
  438. ;
  439. ;    FOR I := 1 TO (TARGET_LEN - LENGTH(STRING)) DO
  440. ;      STRING := STRING + PAD_CHAR;
  441. ;
  442. ; IT IS THE USERS RESPONSIBILITY TO INSURE THAT THE TARGET STRING IS
  443. ; LARGE ENOUGH TO CONTAIN THE EXTRACTED STRING.
  444. ;---------------------------------------------------------------------
  445. PRSTRING    EQU    DWORD PTR [BP+12]    ;STACK POS OF STRING PTR
  446. PRMAXLEN    EQU    WORD  PTR [BP+10]    ;STACK POS OF MAX LENGTH
  447. PRTRGLEN    EQU    WORD  PTR [BP+8]     ;STACK POS OF DESIRED LENGTH
  448. PRCHAR      EQU    BYTE  PTR [BP+6]     ;STACK POS OF PAD CHAR
  449.  
  450. PADRIGHT    PROC   FAR
  451.             PUSH   BP                   ;SAVE BASE POINTER
  452.             MOV    BP,SP                ;SETUP STACK FRAME
  453.             PUSH   DS                   ;SAVE DATA SEGMENT POINTER
  454. ;PRDEBUG:    JMP    PRDEBUG
  455. ;
  456. ; PICK UP THE VARIOUS PARAMETERS
  457. ;
  458.             CLD                         ;DIRECTION = FORWARD
  459.             LDS    SI,PRSTRING          ;LOAD ADDR OF SOURCE STRING
  460.             LES    DI,PRSTRING          ;LOAD STRING PTR AS DESTINATION
  461.             MOV    BX,PRMAXLEN          ;LOAD THE MAXIMUM STRING LEN
  462.             MOV    CX,PRTRGLEN          ;LOAD THE DESIRED LENGTH
  463. ;
  464. ; SEE IF WHAT THE CALLER WANTS WILL FIT
  465. ;
  466.             DEC    BX                   ;DECREMENT FOR LENGTH BYTE
  467.             LODSB                       ;LOAD THE CURRENT STRING LENGTH
  468.             SUB    AH,AH                ;CLEAR HIGH ORDER BYTE
  469.             CMP    AX,BX                ;Q. CUR_LEN => MAX_LEN
  470.             JAE    PREXIT               ;A. YES--THEN JUST QUIT
  471.             CMP    AX,CX                ;Q. CURR_LEN > DESIRED_LEN
  472.             JAE    PREXIT               ;A. YES--THEN NOTHING TO DO
  473.             CMP    CX,BX                ;Q. DESIRED_LEN > MAX_LEN
  474.             JBE    PRSIZEOK             ;A. NO--LENGTHS ARE OKAY
  475.             MOV    CX,BX                ;A. YES--DESIRED_LEN = MAX_LEN
  476. PRSIZEOK:
  477.             SUB    CX,AX                ;PAD_LEN = DESIRED_LEN - CUR_LEN
  478.             MOV    BX,CX                ;SAVE PAD_LEN IN BX
  479. ;
  480. ; FILL THE VACANT SPACE ON THE LEFT WILL 'PRCHAR'
  481. ;
  482.             CLD                         ;DIRECTION = FORWARD
  483.             LES    DI,PRSTRING          ;LOAD ADDR OF STRING AGAIN
  484.             INC    DI                   ;POINT TO 1ST DATA BYTE
  485.             ADD    DI,AX                ;DI ==> 1ST EMPTY BYTE
  486.             MOV    AL,PRCHAR            ;LOAD THE PAD CHARACTER
  487.             MOV    CX,BX                ;RESTORE PAD_LEN
  488.             CLD                         ;SET DIRECTION TO FORWARD
  489.             REP    STOSB                ;PAD THE STRING
  490. ;
  491. ; NOW SET THE NEW LENGTH OF THE STRING
  492. ;
  493.             LDS    SI,PRSTRING          ;LOAD ADDR OF STRING
  494.             MOV    CL,[SI]              ;LOAD CURR_LEN
  495.             SUB    CH,CH                ;CLEAR HIGH BYTE
  496.             ADD    CX,BX                ;NEW_LEN = CURR_LEN + PAD_LEN
  497.             MOV    [SI],CL              ;SET NEW LENGTH OF STRING
  498. ;
  499. ; ALL DONE SO RESTORE THE STUFF WE SAVED AND RETURN TO THE CALLER
  500. ;
  501. PREXIT:
  502.             POP    DS                   ;RESTORE DATA SEGMENT
  503.             POP    BP                   ;RESTORE BASE POINTER
  504.             RET    8                    ;REMOVE AND RETURN
  505. PADRIGHT    ENDP
  506. CODE        ENDS
  507.             END
  508.